Passed
Push — master ( cba44a...8d4558 )
by Rafael S.
01:11
created

index.js ➔ floatToInt_   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 2
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
1
/**
2
 * bitdepth
3
 * Change the resolution of samples to and from 8, 11, 12, 16, 20, 24, 32, 48 & 64-bit.
4
 * Copyright (c) 2017-2018 Rafael da Silva Rocha.
5
 * https://github.com/rochars/bitdepth
6
 *
7
 */
8
9
/** @private */
10
const f64f32_ = new Float32Array(1);
11
12
/**
13
 * Change the bit depth of the data in a array.
14
 * The input array is modified in-place.
15
 * @param {!Array<number>} samples The samples.
16
 * @param {!string} originalBitDepth The original bit depth of the data.
17
 *      One of "8" ... "53", "32f", "64"
18
 * @param {!string} targetBitDepth The desired bit depth for the data.
19
 *      One of "8" ... "53", "32f", "64"
20
 */
21
function toBitDepth(samples, originalBitDepth, targetBitDepth) {
22
    if (originalBitDepth == targetBitDepth) {
23
        return samples;
24
    }
25
    validateBitDepths_(originalBitDepth, targetBitDepth);
26
    let toFunction = getBitDepthFunction_(originalBitDepth, targetBitDepth);
27
    let len = samples.length;
28
    let options = {
29
            oldNegative: parseInt(
30
                Math.pow(2, parseInt(originalBitDepth, 10)) / 2, 10),
31
            newNegative: parseInt(
32
                Math.pow(2, parseInt(targetBitDepth, 10)) / 2, 10),
33
            oldPositive: parseInt(
34
                Math.pow(2, parseInt(originalBitDepth, 10)) / 2 - 1, 10),
35
            newPositive: parseInt(
36
                Math.pow(2, parseInt(targetBitDepth, 10)) / 2 - 1, 10),
37
            original: originalBitDepth,
38
            target: targetBitDepth
39
        };
40
    for (let i=0; i<len; i++) {        
41
        samples[i] = originalBitDepth == "8" ? samples[i] - 128 : samples[i];
42
        samples[i] = toFunction(
43
            samples[i],
44
            options);
45
        samples[i] = targetBitDepth == "8" ? samples[i] + 128 : samples[i];
46
    }
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
47
}
48
49
/**
50
 * Change the bit depth from int to int.
51
 * @param {!number} sample The sample.
52
 * @param {!Object} args Data about the original and target bit depths.
53
 * @return {!number}
54
 * @private
55
 */
56
function intToInt_(sample, args) {
57
    if (sample > 0) {
58
        sample = parseInt(
59
            (sample / args.oldPositive) * args.newPositive, 10);
60
    } else {
61
        sample = parseInt(
62
            (sample / args.oldNegative) * args.newNegative, 10);
63
    }
64
    return sample;
65
}
66
67
/**
68
 * Change the bit depth from float to int.
69
 * @param {!number} sample The sample.
70
 * @param {!Object} args Data about the original and target bit depths.
71
 * @return {!number}
72
 * @private
73
 */
74
function floatToInt_(sample, args) {
75
    return sample > 0 ?
76
        parseInt(sample * args.newPositive, 10) :
77
        parseInt(sample * args.newNegative, 10);
78
}
79
80
/**
81
 * Change the bit depth from int to float.
82
 * @param {!number} sample The sample.
83
 * @param {!Object} args Data about the original and target bit depths.
84
 * @return {!number}
85
 * @private
86
 */
87
function intToFloat_(sample, args) {
88
    return sample > 0 ?
89
        sample / args.oldPositive : sample / args.oldNegative;
90
}
91
92
/**
93
 * Change the bit depth from float to float.
94
 * @param {!number} sample The sample.
95
 * @param {!Object} args Data about the original and target bit depths.
96
 * @return {!number}
97
 * @private
98
 */
99
function floatToFloat_(sample, args) {
0 ignored issues
show
Unused Code introduced by
The parameter args is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
100
    f64f32_[0] = sample;
101
    sample = f64f32_[0];
102
    return sample;
103
}
104
105
/**
106
 * Get the function to change the bit depth of a sample.
107
 * @param {!string} originalBitDepth The original bit depth of the data.
108
 *      One of "8" ... "53", "32f", "64"
109
 * @param {!string} targetBitDepth The new bit depth of the data.
110
 *      One of "8" ... "53", "32f", "64"
111
 * @return {!Function}
112
 * @private
113
 */
114
function getBitDepthFunction_(originalBitDepth, targetBitDepth) {
115
    if (["32f", "64"].includes(originalBitDepth)) {
116
        if (["32f", "64"].includes(targetBitDepth)) {
117
            return floatToFloat_;
118
        } else {
119
            return floatToInt_;
120
        }
121
    } else {
122
        if (["32f", "64"].includes(targetBitDepth)) {
123
            return intToFloat_;
124
        } else {
125
            return intToInt_;
126
        }
127
    }
128
}
129
130
/**
131
 * Validate the bit depth.
132
 * @param {!string} originalBitDepth The original bit depth.
133
 *     Should be one of "8" ... "53", "32f", "64".
134
 * @param {!string} targetBitDepth The target bit depth.
135
 *     Should be one of "8" ... "53", "32f", "64".
136
 * @throws {Error} If any argument does not meet the criteria.
137
 * @return {!boolean}
138
 * @private
139
 */
140
function validateBitDepths_(originalBitDepth, targetBitDepth) {
141
    let validBitDepths = ["32f", "64"];
142
    for (let i=8; i<54; i++) {
143
        validBitDepths.push(i.toString());
144
    }
145
    if (validBitDepths.indexOf(originalBitDepth) == -1 ||
146
        validBitDepths.indexOf(targetBitDepth) == -1) {
147
        throw new Error("Invalid bit depth.");
148
    }
149
    return true;
150
}
151
152
module.exports = toBitDepth;
153
module.exports.toBitDepth = toBitDepth;
154